import { setCookie, getCookie, removeCookie, accessTokenKey, refreshTokenKey } from "@/utils/auth"
import { commonApi } from "@/api"
import router, { resetRouter, routes } from "@/router/index"
import { listArrToTreeArr, getResultSidebarMenuList, generateRoutes } from "vue2-element-admin-plugin"
import {nameComponentObj} from "@/assets/menu/index.js"

const getDefaultState = () => {
  return {
    accessToken: getCookie(accessTokenKey) || "", // 认证token
    refreshToken: getCookie(refreshTokenKey) || "", // 刷新token
    keepLogin: localStorage.getItem("keepLogin") || "0", // 是否保持登录  保持登录的话将 token 存放在sessionStorage
    treeConfig: {
      idField: "menuId", //唯一标识字段名
      parentIdField: "parentMenuId", //父节点唯一标识字段名
      childrenField: "children", //子节点标识字段名
      firstId: null, // 根节点值
      labelField: "menuName", //label字段名
      labelArrField: "labelArr", //给对象新增的中文数组字段名
      idArrField: "pathArr", //给对象新增的id数组字段名
      targetArrField: "path", //目标字段数组  多个可以用 , 分隔开
      levelField: "level", //给对象新增的层级字段名
      level: 1, // 给第一级展示的层级
      leafField: "leaf" //叶子节点标识字段名
    },
    sidePopObj: {
      systemUserManage: {
        popType: "point"
      },
      systemMenuManage: {
        popType: "num",
        num: 66
      }
    }, // 菜单栏上的气泡
    userInfo: {
      userId: null,
      userName: "",
      avatar: "",
      email: ""
    }, // 用户信息
    roleIdList: [], // 用户角色id列表
    permissionList: [], // 用户按钮权限
    sqlTableList: [], // 数据表权限标识 回收站使用
    sidebarMenuTree: [], // 侧边菜单树 数据
    sidebarMenuList: [], // 侧边菜单列表
    allMenuList: [], // 全部菜单数据 包含按钮
    isEncrypt: false // 是否对接口进行加密
  }
}
const state = getDefaultState()

const mutations = {
  // 重置初始化值
  RESET_STATE: (state) => {
    Object.assign(state, getDefaultState())
  },
  // 设置token
  SET_TOKEN: (state, data) => {
    const { accessToken, refreshToken, reFreshExpiresIn, tokenExpiresIn} = data
    // 保持登录时 AccessToken的存储时间和refreshToken一样    不保持登录时 AccessToken的存储有效时间为 真实有效时间
    const expiresIn = state.keepLogin === "1" ? reFreshExpiresIn : tokenExpiresIn
    state.accessToken = accessToken
    setCookie(accessTokenKey, accessToken, expiresIn/1000)
    state.refreshToken = refreshToken
    setCookie(refreshTokenKey, refreshToken, expiresIn/1000)
  },
  SET_USER_INFO: (state, userInfo) => {
    state.userInfo = userInfo
  },
  // 清除token
  CLEAR_AUTH: (state) => {
    state.accessToken = ""
    removeCookie(accessTokenKey)
    state.refreshToken = ""
    removeCookie(refreshTokenKey)
  },
  // 设置按钮权限
  SET_PERMISSION_LIST: (state, permissionList) => {
    state.permissionList = permissionList
  },
  // 数据表权限标识
  SET_SQL_TABLE_LIST: (state, sqlTableList) => {
    state.sqlTableList = sqlTableList
  },
  // 设置用户角色id列表
  SET_ROLE_ID_LIST: (state, roleIdList) => {
    state.roleIdList = roleIdList
  },
  // 设置侧边菜单树
  SET_SIDEBAR_MENU_TREE: (state, sidebarMenuTree) => {
    state.sidebarMenuTree = sidebarMenuTree
  },
  // 设置侧边菜单数据
  SET_SIDEBAR_MENU_LIST: (state, sidebarMenuList) => {
    state.sidebarMenuList = sidebarMenuList
  },
  // 设置所有菜单数据
  SET_ALL_MENU_LIST: (state, menuList) => {
    state.allMenuList = menuList
  },
  // 设置是否进行接口加密
  SET_IS_ENCRYPT: (state, isEncrypt) => {
    state.isEncrypt = isEncrypt
  },
  // 设置保持登录
  SET_KEEP_LOGIN: (state, keepLogin) => {
    state.keepLogin = keepLogin
    localStorage.setItem("keepLogin", keepLogin)
  },
  // 存储refreshToken
  SET_REFRESH_TOKEN: (state, refreshToken) => {
    state.refreshToken = refreshToken
    setCookie(refreshTokenKey, refreshToken)
  }
}

const actions = {
  // 设置项目token
  setToken({commit}, data) {
    return new Promise((resolve, reject) => {
      commit("SET_TOKEN", data)
      resolve()
    })
  },
  // 获取用户信息
  getUserInfo({state, commit}) {
    return new Promise((resolve, reject) => {
      commonApi.getUserInfo().then(data => {
        const { userInfo, permissionList, sqlTableList, menuList, roleIdList, isEncrypt, refreshToken} = data
        commit("SET_IS_ENCRYPT", isEncrypt)
        commit("SET_USER_INFO", userInfo)
        commit("SET_PERMISSION_LIST", permissionList)
        commit("SET_SQL_TABLE_LIST", sqlTableList)
        commit("SET_ROLE_ID_LIST", roleIdList)
        commit("SET_ALL_MENU_LIST", menuList)

        // 不保持登录时 由于refreshToken存储在sessionStorage 避免丢失 在此处设置一下
        if (state.keepLogin === "0") {
          commit("SET_REFRESH_TOKEN", refreshToken)
        }

        // 重置路由
        resetRouter()

        const resultSidebarMenuList = getResultSidebarMenuList(menuList)
        commit("SET_SIDEBAR_MENU_LIST", resultSidebarMenuList)
        const sidebarMenuTree = listArrToTreeArr(resultSidebarMenuList, state.treeConfig)
        // 插入首页
        const dashboard = nameComponentObj["dashboard"]
        sidebarMenuTree.unshift(dashboard)
        commit("SET_SIDEBAR_MENU_TREE", sidebarMenuTree)

        // 找到所有页面菜单
        const pageMenuList = menuList.filter(item => {
          return item.menuType === "1"
        })
        const constantRoutes = routes
        const resultRouters = generateRoutes(constantRoutes, pageMenuList, nameComponentObj)
        router.addRoutes(resultRouters)
        resolve()
      })
    })
  },
  // 刷新token
  refreshToken({commit}, refreshToken) {
    return new Promise((resolve, reject) => {
      commonApi.refreshToken({refreshToken}).then(data => {
        commit("SET_TOKEN", data)
        resolve()
      })
    })
  },
  //退出登录
  logout({ commit, dispatch }) {
    return new Promise((resolve, reject) => {
      commonApi.logout().then(() => {
        // 清除token
        commit("CLEAR_AUTH")
        // 重置state数据
        commit("RESET_STATE")

        // 设置保持登录为0
        commit("SET_KEEP_LOGIN", "0")

        // 清空tag标签栏
        dispatch("tagsView/delAllViewsIncludeAffix", {}, { root: true })
        resolve()
      }).catch(error => {
        reject(error)
      })
    })
  }
}

export default {
  namespaced: true,
  state,
  mutations,
  actions
}

